
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class GUI {

	private BurningForstSimulation simulation;

	private Display display;
	public Canvas canvas;
	private Text d;
	private Text g;
	private Text f;
	private Text p;
	private GUIUpdater updater;

	private Button plantButton;

	private Button startButton;

	private Button stopButton;

	public void startRun() {
		display = new Display();
		Shell shell = new Shell(display, SWT.TITLE | SWT.MIN | SWT.CLOSE);
		shell.setText("Burning Forest Simulation");
		createContents(shell);
		shell.setSize(640, 725);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	
		display.dispose();
	}

	private void createContents(Shell shell) {
		shell.setLayout(new GridLayout(1, false));

		// Create a canvas

		Group group1 = new Group(shell, SWT.SHADOW_IN);

		group1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		plantButton = new Button(group1, SWT.PUSH);
		plantButton.setBounds(10, 15, 60, 30);
		plantButton.setText("Plant");

		plantButton.addSelectionListener(new SelectionListener() {

			public void widgetSelected(SelectionEvent event) {
				plaentTrees();
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
				// TODO Auto-generated method stub

			}

		});

		startButton = new Button(group1, SWT.PUSH);
		startButton.setBounds(75, 15, 50, 30);
		
		startButton.setText("Start");
		startButton.setEnabled(false);

		startButton.addSelectionListener(new SelectionListener() {

			public void widgetSelected(SelectionEvent event) {
				startSimulation();
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
				// TODO Auto-generated method stub

			}

		});

		startButton.setEnabled(false);

		stopButton = new Button(group1, SWT.PUSH);
		stopButton.setBounds(130, 15, 50, 30);
		stopButton.setText("Stop");

		stopButton.addSelectionListener(new SelectionListener() {

			public void widgetSelected(SelectionEvent event) {
				stopSimulation();
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
			}

		});
		stopButton.setEnabled(false);

		Label l = new Label(group1, SWT.NONE);
		l.setBounds(200, 20, 10, 30);
		l.setText("d:");
		this.d = new Text(group1, SWT.NONE);
		d.setText("0.5");
		d.setBounds(215, 20, 50, 18);
		
		l = new Label(group1, SWT.NONE);
		l.setBounds(275, 20, 10, 30);
		l.setText("g:");
		this.g = new Text(group1, SWT.NONE);
		g.setText("0.5");
		g.setBounds(290, 20, 50, 18);
		g.setEnabled(false);
		
		l = new Label(group1, SWT.NONE);
		l.setBounds(350, 20, 10, 30);
		l.setText("f:");
		this.f = new Text(group1, SWT.NONE);
		f.setText("0.5");
		f.setBounds(365, 20, 50, 18);
		f.setEnabled(false);
		
		l = new Label(group1, SWT.NONE);
		l.setBounds(420, 20, 10, 30);
		l.setText("p:");
		this.p= new Text(group1, SWT.NONE);
		p.setText("0.5");
		p.setBounds(435, 20, 50, 18);
		p.setEnabled(false);
		
		
		canvas = new Canvas(shell, SWT.NONE);
		canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 2, 1));
		// Create a paint handler for the canvas
		canvas.setSize(1000, 1000);
		canvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {

				if (simulation != null) {
					int h = 1;
					int l = 1;

					for (int i = 0; i < simulation.matrix.length; i++) {
						h = 1;
						for (int j = 0; j < simulation.matrix[i].length; j++) {
							char state = simulation.matrix[i][j].cellState;
							if (state == TreeCell.EMPTY_CELL) {
								e.gc.setForeground(e.display
										.getSystemColor(SWT.COLOR_BLUE));
								e.gc.setBackground(e.display
										.getSystemColor(SWT.COLOR_BLUE));
							}
							if (state == TreeCell.BURNING_TREE_CELL) {
								e.gc.setForeground(e.display
										.getSystemColor(SWT.COLOR_RED));
								e.gc.setBackground(e.display
										.getSystemColor(SWT.COLOR_RED));
							}
							if (state == TreeCell.TREE_CELL) {

								e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_GREEN));
								e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_GREEN));
							}
							e.gc.drawRectangle(h, l, Constants.PIXEL_SIZE,Constants.PIXEL_SIZE);
							e.gc.fillRectangle(h, l, Constants.PIXEL_SIZE,Constants.PIXEL_SIZE);
							h += Constants.PIXEL_SIZE + 1;
						}
						l += Constants.PIXEL_SIZE + 1;
					}
				}
			}
		});

	}

	public BurningForstSimulation getSimulation() {
		return simulation;
	}

	/**
	 * this method performs the planting of the trees in the gui
	 * 
	 */
	private void plaentTrees() {
		this.simulation = new BurningForstSimulation();
		this.simulation.d_plantingProb=Double.parseDouble(this.d.getText());
		
		simulation.initCellularAutomaton();
		g.setEnabled(true);
		f.setEnabled(true);
		p.setEnabled(true);

		startButton.setEnabled(true);

		canvas.redraw();

	}

	/**
	 * This method start the simulation
	 * 
	 */
	public void startSimulation() {
		this.simulation.g_combustibilityProb=Double.parseDouble(this.g.getText());
		this.simulation.f_lightningStrikeProb=Double.parseDouble(this.f.getText());
		this.simulation.p_growNewPlantProb=Double.parseDouble(this.p.getText());
		
		startButton.setEnabled(false);
		plantButton.setEnabled(false);
		stopButton.setEnabled(true);

		this.updater = new GUIUpdater(display, this);
		updater.setDaemon(true);
		updater.start();

	}

	/**
	 * This mehtod stops the simulation
	 * 
	 */
	public void stopSimulation() {
		updater.stopSim();
	}

	/**
	 * This method is called form the gui update thread and repaint the territory again
	 * 
	 */
	public void evolveToNextGeneration() {
		simulation.evolveToNextGeneration();
		canvas.redraw();
	}

	/**
	 * 
	 * This method is called when the automaton stops its running
	 * 
	 */
	public void endRunning() {
		startButton.setEnabled(true);
		plantButton.setEnabled(true);
		stopButton.setEnabled(false);
		
	}

}
